package com.gxd.es.service;

import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Map;

public class ElasticTransportClient {

    public static TransportClient client =  ElasticTransportClient.initESClient();


    public static TransportClient initESClient() throws NumberFormatException {

        TransportClient esclient= null;

        try {
            Settings settings = Settings.builder()
                    .put("cluster.name", "dataservercenteres").build();
            esclient = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.13.3"), 9300))
                    .addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.13.4"), 9300));

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

  /*      try {
            Settings settings = Settings.builder()
                    .put("cluster.name", "gxdescluster").build();
            esclient = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.50.33"), 9300));

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }*/

        return esclient;
    }

    public MultiSearchResponse search(String key, String cityCode) {


        SearchRequestBuilder srb1 =  ElasticTransportClient.client.prepareSearch("address")
                .setTypes("address")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.boolQuery().should(QueryBuilders.matchPhraseQuery("DESCRIPTION",key))
                        .should(QueryBuilders.matchPhraseQuery("FULL_NAME",key)))
                        .must(QueryBuilders.termQuery("CITY_CODE",cityCode))
                        .mustNot(QueryBuilders.termQuery("ADDR_STATUS_CD",2))
                        .filter(QueryBuilders.rangeQuery("ADDR_TYPE_CD").from(5).to(7)))
                .setSize(10);
        SearchRequestBuilder srb2 =  ElasticTransportClient.client.prepareSearch("street")
                .setTypes("street")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("STREET",key))
                        .must(QueryBuilders.termQuery("CITY_CODE",cityCode))
                        .mustNot(QueryBuilders.termQuery("STATUS",2))
                        .filter(QueryBuilders.rangeQuery("ADDR_TYPE_CD").from(5).to(7)))
                .setSize(2);
        SearchRequestBuilder srb3 =  ElasticTransportClient.client.prepareSearch("addressalias")
                .setTypes("addressalias")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("ADDRESS_NAME",key))
                        .must(QueryBuilders.termQuery("CITY_CODE",cityCode))
                        .mustNot(QueryBuilders.termQuery("STATUS",2))
                        .filter(QueryBuilders.rangeQuery("ADDR_TYPE_CD").from(5).to(7)))
                .setSize(2);


        MultiSearchResponse response = ElasticTransportClient.client.prepareMultiSearch()
                .add(srb1)
                .add(srb2)
                .add(srb3)
                .get();

        return response;
    }

    public SearchResponse caseSearch(Map<String,String> paramers) {

        SearchRequestBuilder prepareSearch = null;

        try{
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
            //判断访问的案例类型
            if(paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("SALE")){
                prepareSearch = client.prepareSearch("sale");
                prepareSearch.setTypes("sale");
                if(paramers.get("htmlId")!= null && paramers.get("htmlId").toUpperCase().equals("FIRST")){
                    queryBuilder.must(QueryBuilders.termQuery("SALETYPE","1"));
                }else if(paramers.get("htmlId")!= null && paramers.get("htmlId").toUpperCase().equals("SECOND")){
                    queryBuilder.must(QueryBuilders.termQuery("SALETYPE","2"));
                }
            }else if (paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("NET_LISTING")){
                prepareSearch = client.prepareSearch("netlisting");
                prepareSearch.setTypes("netlisting");
            }else if (paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("OWNERSHIP")){
                prepareSearch = client.prepareSearch("ownership");
                prepareSearch.setTypes("ownership");
            }else if (paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("TAX")){
                prepareSearch = client.prepareSearch("tax");
                prepareSearch.setTypes("tax");
            }else if (paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("ASSESS")){
                prepareSearch = client.prepareSearch("assess");
                prepareSearch.setTypes("assess");
            }else if (paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("MORTGAGE")){
                prepareSearch = client.prepareSearch("mortgage");
                prepareSearch.setTypes("mortgage");
            }else if (paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("RENT")){
                prepareSearch = client.prepareSearch("rent");
                prepareSearch.setTypes("rent");
            }else if (paramers.get("tableNameFront")!= null && paramers.get("tableNameFront").toUpperCase().equals("FORECLOSURE")){
                prepareSearch = client.prepareSearch("foreclosure");
                prepareSearch.setTypes("foreclosure");
            }

            //判断是小区、楼栋、单元
            if(paramers.get("caseId")!= null && paramers.get("caseId").toUpperCase().equals("COMMUNITY_ID") && paramers.get("addressId")!= null){
                queryBuilder.must(QueryBuilders.termQuery("COMMUNITY_ID",paramers.get("addressId")));
            }else if(paramers.get("caseId")!= null && paramers.get("caseId").toUpperCase().equals("BUILDING_ID") && paramers.get("addressId")!= null){
                queryBuilder.must(QueryBuilders.termQuery("BUILDING_ID",paramers.get("addressId")));
            }else if(paramers.get("caseId")!= null && paramers.get("caseId").toUpperCase().equals("UNIT_ID") && paramers.get("addressId")!= null){
                queryBuilder.must(QueryBuilders.termQuery("UNIT_ID",paramers.get("addressId")));
            }else if(paramers.get("caseId")!= null && paramers.get("caseId").toUpperCase().equals("HOUSE_ID") && paramers.get("addressId")!= null){
                queryBuilder.must(QueryBuilders.termQuery("HOUSE_ID",paramers.get("addressId")));
            }


            //案例使用情况
            if(paramers.get("tradeType")!= null){
                if(paramers.get("tradeType").equals("1008611")){
                    queryBuilder.must(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("ISDELETED","0"))
                            .should(QueryBuilders.termQuery("ISDELETED","2")));
                }else{
                    queryBuilder.must(QueryBuilders.termQuery("ISDELETED",paramers.get("tradeType")));
                }
            }
            //判断案例日期
            if(paramers.get("thadeDateFilter")!= null){
                if(paramers.get("thadeDateFilter").equals("1008611")){

                }else{
                    queryBuilder.must(QueryBuilders.rangeQuery("UPDATETIME").gte("now"+paramers.get("thadeDateFilter")+"M/d"));
                }
            }
            //判断是否人工添加
            if(paramers.get("thadeIfArtificialInsert")!= null){
                if(paramers.get("thadeIfArtificialInsert").equals("1008611")){

                }else if(paramers.get("thadeIfArtificialInsert").equals("0")){
                    queryBuilder.must(QueryBuilders.existsQuery("staff_Id"));
                }else{
                    queryBuilder.mustNot(QueryBuilders.existsQuery("staff_Id"));
                }
            }

            //判断添加分页
            if(paramers.get("pageNumber")!= null && paramers.get("pageSize")!= null){
                prepareSearch.setFrom(Integer.valueOf(paramers.get("pageNumber"))*10);
                prepareSearch.setSize(Integer.valueOf(paramers.get("pageSize")));
            }

            //判断添加排序
            if(paramers.get("sortOrder")!= null){
                if(paramers.get("orderDate")!= null){
                    prepareSearch.addSort(paramers.get("orderDate"), SortOrder.DESC);
                }
            }

            prepareSearch.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
            prepareSearch.setQuery(queryBuilder);
            prepareSearch.setExplain(true);

        }catch(Exception e ){
            e.printStackTrace();
        }
        return prepareSearch.get();
    }


    public SearchResponse userAccessSearch(Map<String,String> paramers) {

        SearchRequestBuilder prepareSearch = client.prepareSearch("useraccesslog");
        prepareSearch.setTypes("useraccesslog");

        try{

            prepareSearch.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
            AggregationBuilder aggregationBuilder = AggregationBuilders.terms("BY_RESOURCE_URL").field("RESOURCE_URL.keyword")
                    .subAggregation(AggregationBuilders.terms("BY_RESOURCE_NAME").field("RESOURCE_NAME.keyword")
                            .subAggregation(AggregationBuilders.terms("BY_ACCESS_LIMIT_LEVEL").field("ACCESS_LIMIT_LEVEL.keyword")
                                    .subAggregation(AggregationBuilders.terms("BY_LOGIN_STAFF").field("LOGIN_STAFF.keyword")
                                            .subAggregation(AggregationBuilders.terms("BY_STAFF_NAME").field("STAFF_NAME.keyword")
                                                    .subAggregation(AggregationBuilders.dateHistogram("BY_REQUEST_DATE").field("REQUEST_DATE").format("HH").dateHistogramInterval(DateHistogramInterval.HOUR)
                                                            .subAggregation(AggregationBuilders.filter("BY_LIMIT_ID", QueryBuilders.existsQuery("LIMIT_ID.keyword"))))))));

            //用户访问资源名称
            if(paramers.get("resourceName")!= null){
                queryBuilder.must(QueryBuilders.wildcardQuery("RESOURCE_NAME.keyword","*"+paramers.get("resourceName")+"*"));
            }
            //用户访问日志时间
            if(paramers.get("logDate")!= null){
                queryBuilder.must(QueryBuilders.rangeQuery("REQUEST_DATE").gte(paramers.get("logDate")+" 00:00:00").lte(paramers.get("logDate")+" 23:59:59"));

            }
            //用户访问编号
            if(paramers.get("staffNum")!= null){

                queryBuilder.must(QueryBuilders.matchPhraseQuery("STAFF_NAME",paramers.get("staffNum")));
            }
            //判断添加分页
            if(paramers.get("page")!= null && paramers.get("rows")!= null){
                prepareSearch.setFrom(Integer.valueOf(paramers.get("page"))*10);
                prepareSearch.setSize(Integer.valueOf(0));
            }

            prepareSearch.setQuery(queryBuilder);
            prepareSearch.addAggregation(aggregationBuilder);
            prepareSearch.setExplain(true);

        }catch(Exception e ){

        }
        return prepareSearch.get();

    }

    public SearchResponse termsSearch(HashSet<String> addressidSet) {

        SearchResponse response = client.prepareSearch("address")
                .setTypes("address")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(QueryBuilders.termsQuery("ADDRESS_ID",addressidSet))
                .setPostFilter(QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery("ADDR_STATUS_CD",2)))
                .setExplain(true)
                .get();

        return response;
    }
}
